package ci.web.core;

import java.io.File;
import java.net.SocketAddress;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import com.alibaba.fastjson.JSONAware;
import com.alibaba.fastjson.JSONObject;

import ci.web.HttpMethod;
import ci.web.codec.FileItem;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.cookie.Cookie;

/**
 * 请求上下文
 * @author zhh
 */
public class CiContext implements CiRequest, CiResponse {

    /**
     * 未完成的CiContext-计数器
     */
    public static final AtomicInteger counter = new AtomicInteger();
    
    protected CiRequest request;
    protected CiResponse response;

    public CiContext(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception{
        this(
                new CiRequestImp(ctx, req),
                new CiResponseImp(ctx, req)
                );
    }

    public CiContext(CiRequest request, CiResponse response) {
        this.request = request;
        this.response = response;
        counter.incrementAndGet();
    }

    public CiRequest in() {
        return request;
    }
    public CiResponse out() {
        return response;
    }
    
    public void finish(){
        if(isFinish()==false){
            counter.decrementAndGet();
            response.finish();
            request.finish();
        }
    }
    public boolean isFinish(){
        return request.isFinish() && response.isFinish();
    }
    @Override
    public synchronized void cleanFinish(){
    	if(isFinish()==false){
    		counter.decrementAndGet();
    		request.finish();
    		response.cleanFinish();
    	}
    }
    @Override
    public ChannelHandlerContext ioContext(){
    	return response.ioContext();
    }
    
    private boolean async=false;
    /**
     * 设置为异步请求, 比如，在专门的线程处理，或者异步等待数据情况时。<br/>
     * 需要自己在结束后，调用 finish来输出内容<br/>
     */
    public void setAsync(){
        if(!isFinish()){
            async = true;
        }
    }
    /**
     * 是否异步请求
     * @return
     */
    public boolean isAsync(){
        return async;
    }

    @Override
    public void setStatus(HttpResponseStatus status) {
        response.setStatus(status);
    }

    @Override
    public void setStatus(int statusCode, CharSequence statusInfo) {
        response.setStatus(statusCode, statusInfo);
    }

    @Override
    public void setContentType(CharSequence contentType) {
        response.setContentType(contentType);        
    }

    @Override
    public void setHeader(CharSequence name, CharSequence value) {
        response.setHeader(name, value);
    }

    @Override
    public void setCookie(Cookie cookie) {
        response.setCookie(cookie);
    }

    @Override
    public void setCookie(String name, String value) {
        response.setCookie(name, value);
    }

    @Override
    public void setCookie(String name, String value, long maxAge) {
        response.setCookie(name, value, maxAge);
    }

    @Override
    public void setCookie(String name, String value, long maxAge, String path,
            String domain, boolean secure, boolean httpOnly) {
        response.setCookie(name, value, maxAge, path, domain, secure, httpOnly);
    }

    @Override
    public void redirect(CharSequence location) {
        response.redirect(location);
    }

    @Override
    public void redirect(CharSequence location, int httpStatusCode) {
        response.redirect(location, httpStatusCode);
    }

    @Override
    public void sendError(CharSequence errorInfo) {
        response.sendError(errorInfo);
    }

    @Override
    public void sendError(int code, CharSequence errorInfo) {
        response.sendError(code, errorInfo);
    }

    @Override
    public void send(File file) {
        response.send(file);
    }
    @Override
    public void send(File file, int fileCacheSecond) {
        response.send(file, fileCacheSecond);
    }

    @Override
    public void send(JSONAware ret) {
        response.send(ret);
    }

    @Override
    public void send(CharSequence body) {
        response.send(body);
    }

    @Override
    public void send(byte[] body) {
        response.send(body);
    }

    @Override
    public boolean isWroteBody() {
    	return response.isWroteBody();
    }
    
    @Override
    public HttpMethod method() {
        return request.method();
    }

    @Override
    public String refererHost() {
        return request.refererHost();
    }
    
    @Override
    public String host() {
        return request.host();
    }
    
    @Override
    public String uri() {
        return request.uri();
    }

    @Override
    public String path() {
        return request.path();
    }

    @Override
    public SocketAddress address() {
        return request.address();
    }

    @Override
    public JSONObject params() {
        return request.params();
    }
    @Override
    public JSONObject post() {
        return request.post();
    }
    @Override
    public JSONObject get() {
        return request.get();
    }
    
    @Override
    public byte[] body() {
        return request.body();
    }

    @Override
    public List<FileItem> files() {
        return request.files();
    }

    @Override
    public FileItem getFile(String name) {
        return request.getFile(name);
    }

    @Override
    public HttpHeaders headers() {
        return request.headers();
    }

    @Override
    public String getHeader(CharSequence name) {
        return request.getHeader(name);
    }

    @Override
    public Set<Cookie> cookies() {
        return request.cookies();
    }

    @Override
    public Cookie getCookie(CharSequence name) {
        return request.getCookie(name);
    }

    @Override
    public String getCookieValue(CharSequence name) {
        return request.getCookieValue(name);
    }

    @Override
    public String contentType() {
        return request.contentType();
    }

}
